package com.bzgwl.mybatis_plus.security;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Author: Professor_Kong
 * date: 2018/3/22
 */
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {
    /**
     * 验证用户是否有权限访问资源
     * @param authentication
     * @param o
     * @param configAttributes
     * @throws AccessDeniedException
     * @throws InsufficientAuthenticationException
     */
    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        /*允许访问没有设置权限的资源*/
        if(configAttributes == null) {
            return;
        }
        /*一个资源可以由多个权限访问，用户拥有其中一个权限即可访问该资源*/
        Iterator<ConfigAttribute> configIterator = configAttributes.iterator();


        //当前用户拥有的角色
        Set<String> havePer = new HashSet<>();

        for(GrantedAuthority ga : authentication.getAuthorities()) {
            havePer.add(ga.getAuthority().trim());
        }

        while (configIterator.hasNext()) {
            ConfigAttribute configAttribute = configIterator.next();
            String needPermission = configAttribute.getAttribute();

            System.out.println("需要的权限："+needPermission);
            System.out.println("当前权限集合："+ havePer.toString());
            havePer.contains(needPermission); //交集
            if(havePer.size() > 0){
                return;
            }
        }
        throw new AccessDeniedException("没有权限访问");
    }

    /**
     * 特定configAttribute的支持
     * @param configAttribute
     * @return
     */
    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        /*支持所有configAttribute*/
        return true;
    }

    /**
     * 特定安全对象类型支持
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(Class<?> aClass) {
        /*支持所有对象类型*/
        return true;
    }
}